package com.sumer.psychology.blog.infrastructure.messaging.rabbitmq;

import com.google.common.collect.ImmutableMap;
import com.sumer.psychology.blog.domain.model.BlogAvailability;
import com.sumer.psychology.blog.infrastructure.persistence.mongo.MongoBlogRepository;
import com.sumer.psychology.blog.infrastructure.persistence.mongo.MongoCategoryListRepository;
import com.sumer.psychology.blog.infrastructure.persistence.redis.RedisBlogRepository;
import com.sumer.psychology.common.notification.NotificationReader;
import com.sumer.psychology.common.port.adapter.messaging.Exchanges;
import com.sumer.psychology.common.port.adapter.messaging.rabbitmq.ExchangeListener;

import java.util.Map;

/**
 * 博客变更监听
 * 1.更新
 * 2.回收站
 * 3.恢复
 * 4.分类
 * <p/>
 * Created by zhu on 14-10-12.
 */
public class BlogChangedEventListener extends ExchangeListener {
    private static final String CHANGED_TYPE = "com.sumer.psychology.blog.domain.model.BlogChangedEvent";
    private static final String RECYCLE_TYPE = "com.sumer.psychology.blog.domain.model.BlogPutToRecycleBinEvent";
    private static final String RESTORE_TYPE = "com.sumer.psychology.blog.domain.model.BlogRestoredEvent";
    private static final String CLASSIFY_TYPE = "com.sumer.psychology.blog.domain.model.BlogClassifiedEvent";

    private static final Map<String, BlogAvailability> TYPE_MAP = ImmutableMap.of(
            RECYCLE_TYPE, BlogAvailability.DEACTIVE,
            RESTORE_TYPE, BlogAvailability.ACTIVE);

    private MongoBlogRepository mongoBlogRepository;
    private MongoCategoryListRepository mongoCategoryListRepository;
    private RedisBlogRepository redisBlogRepository;

    public BlogChangedEventListener(MongoBlogRepository mongoBlogRepository,
                                    MongoCategoryListRepository mongoCategoryListRepository,
                                    RedisBlogRepository redisBlogRepository) {
        this.mongoBlogRepository = mongoBlogRepository;
        this.mongoCategoryListRepository = mongoCategoryListRepository;
        this.redisBlogRepository = redisBlogRepository;
    }

    @Override
    protected String exchangeName() {
        return Exchanges.DEFAULT_EXCHANGE_NAME;
    }

    @Override
    protected void filteredDispatch(String aType, String aTextMessage) {
        switch (aType) {
            case CHANGED_TYPE:
                mongoBlogRepository.change(aTextMessage);
                break;
            case CLASSIFY_TYPE:
                mongoCategoryListRepository.changeBlogSize(aTextMessage);
                mongoBlogRepository.change(aTextMessage);
                break;
            case RECYCLE_TYPE:
                mongoBlogRepository.change(aTextMessage, TYPE_MAP.get(aType));
                mongoCategoryListRepository.removeBlog(blogId(aTextMessage));
                recordToStatistic(aTextMessage);
                break;
            case RESTORE_TYPE:
                mongoBlogRepository.change(aTextMessage, TYPE_MAP.get(aType));
                mongoCategoryListRepository.restoreBlog(blogId(aTextMessage));
                break;
        }
    }

    private void recordToStatistic(String aTextMessage) {
        NotificationReader reader = new NotificationReader(aTextMessage);
        String blogId = reader.eventStringValue("blogId.identity");
        redisBlogRepository.remove(blogId);
    }

    private String blogId(String aTextMessage) {
        NotificationReader reader = new NotificationReader(aTextMessage);
        return reader.eventStringValue("blogId.identity");
    }

    @Override
    protected String[] listensTo() {
        return new String[]{
                CHANGED_TYPE,
                RECYCLE_TYPE,
                RESTORE_TYPE,
                CLASSIFY_TYPE};
    }
}
